---
title: "Python 面向对象与函数式编程"
description: "从 JavaScript 开发者视角学习 Python 的面向对象编程、函数式编程特性和装饰器"
---

## 1. 引言

### 为什么学习面向对象和函数式编程？

作为 JavaScript 开发者，你可能已经熟悉了 ES6 的类语法和函数式编程概念。Python 在这两个方面都有独特的实现方式，掌握这些特性将让你能够：

- 编写更优雅和可维护的代码
- 理解 Python 的设计哲学
- 利用 Python 强大的元编程能力
- 构建更复杂的应用程序

> 💡 **学习策略**：将 Python 的 OOP 和函数式特性视为 JavaScript 概念的"增强版本"

## 2. 面向对象编程（OOP）

### 2.1 类的基本概念

Python 的类系统与 JavaScript 的类有很多相似之处，但也有一些重要的差异。

<PythonEditor title="类的基本定义对比" compare={true}>
```javascript !! js
// JavaScript 类定义
class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    
    // 实例方法
    sayHello() {
        return `你好，我是 ${this.name}，今年 ${this.age} 岁`;
    }
    
    // 静态方法
    static create(name, age) {
        return new Person(name, age);
    }
    
    // Getter
    get info() {
        return `${this.name} (${this.age})`;
    }
    
    // Setter
    set info(value) {
        const [name, age] = value.split(' ');
        this.name = name;
        this.age = parseInt(age);
    }
}

// 使用类
const person = new Person("张三", 25);
console.log(person.sayHello());
console.log(person.info);
person.info = "李四 30";
console.log(person.name); // "李四"
```

```python !! py
# Python 类定义
class Person:
    """人类类"""
    
    def __init__(self, name, age):
        """构造函数（类似 JavaScript 的 constructor）"""
        self.name = name
        self.age = age
    
    def say_hello(self):
        """实例方法（类似 JavaScript 的实例方法）"""
        return f"你好，我是 {self.name}，今年 {self.age} 岁"
    
    @staticmethod
    def a_static_method():
        """静态方法，无法访问类或实例"""
        return "这是一个静态方法"
    
    @classmethod
    def create(cls, name, age):
        """类方法（类似 JavaScript 的静态方法）"""
        return cls(name, age)
    
    @property
    def info(self):
        """属性装饰器（类似 JavaScript 的 getter）"""
        return f"{self.name} ({self.age})"
    
    @info.setter
    def info(self, value):
        """属性设置器（类似 JavaScript 的 setter）"""
        name, age = value.split(' ')
        self.name = name
        self.age = int(age)
    
    def __str__(self):
        """字符串表示（类似 JavaScript 的 toString）"""
        return f"Person({self.name}, {self.age})"

# 使用类
person = Person("张三", 25)
print(person.say_hello())
print(person.info)
person.info = "李四 30"
print(person.name)  # "李四"
print(person)  # Person(李四, 30)
```
</PythonEditor>

### 2.2 类变量与实例变量

Python 中的类变量和实例变量概念与 JavaScript 中的静态属性和实例属性类似。

<PythonEditor title="类变量与实例变量" compare={true}>
```javascript !! js
// JavaScript 类变量和实例变量
class Counter {
    // 类变量（静态属性）
    static totalCount = 0;
    static instances = [];
    
    constructor() {
        // 实例变量
        this.count = 0;
        Counter.totalCount++;
        Counter.instances.push(this);
    }
    
    increment() {
        this.count++;
        Counter.totalCount++;
    }
    
    static getTotalCount() {
        return Counter.totalCount;
    }
    
    static getAllInstances() {
        return Counter.instances;
    }
}

const counter1 = new Counter();
const counter2 = new Counter();

counter1.increment();
counter2.increment();
counter2.increment();

console.log(counter1.count);           // 1
console.log(counter2.count);           // 2
console.log(Counter.getTotalCount());  // 3
console.log(Counter.getAllInstances().length); // 2
```

```python !! py
# Python 类变量和实例变量
class Counter:
    """计数器类"""
    
    # 类变量（类似 JavaScript 的静态属性）
    total_count = 0
    instances = []
    
    def __init__(self):
        """构造函数"""
        # 实例变量
        self.count = 0
        Counter.total_count += 1
        Counter.instances.append(self)
    
    def increment(self):
        """增加计数"""
        self.count += 1
        Counter.total_count += 1
    
    @classmethod
    def get_total_count(cls):
        """获取总计数（类方法）"""
        return cls.total_count
    
    @classmethod
    def get_all_instances(cls):
        """获取所有实例（类方法）"""
        return cls.instances

# 创建实例
counter1 = Counter()
counter2 = Counter()

counter1.increment()
counter2.increment()
counter2.increment()

print(counter1.count)                    # 1
print(counter2.count)                    # 2
print(Counter.get_total_count())         # 3
print(len(Counter.get_all_instances()))  # 2
```
</PythonEditor>

### 2.3 继承与多态

Python 的继承系统比 JavaScript 更加直观和强大。

<PythonEditor title="继承与多态" compare={true}>
```javascript !! js
// JavaScript 继承
class Animal {
    constructor(name) {
        this.name = name;
    }
    
    speak() {
        return `${this.name} 发出声音`;
    }
    
    move() {
        return `${this.name} 在移动`;
    }
}

class Dog extends Animal {
    constructor(name, breed) {
        super(name);
        this.breed = breed;
    }
    
    speak() {
        return `${this.name} 汪汪叫`;
    }
    
    fetch() {
        return `${this.name} 在捡球`;
    }
}

class Cat extends Animal {
    constructor(name, color) {
        super(name);
        this.color = color;
    }
    
    speak() {
        return `${this.name} 喵喵叫`;
    }
    
    climb() {
        return `${this.name} 在爬树`;
    }
}

// 多态示例
const animals = [
    new Dog("旺财", "金毛"),
    new Cat("咪咪", "橘色")
];

animals.forEach(animal => {
    console.log(animal.speak());
    console.log(animal.move());
});
```

```python !! py
# Python 继承
class Animal:
    """动物基类"""
    
    def __init__(self, name):
        self.name = name
    
    def speak(self):
        """发出声音"""
        return f"{self.name} 发出声音"
    
    def move(self):
        """移动"""
        return f"{self.name} 在移动"

class Dog(Animal):
    """狗类"""
    
    def __init__(self, name, breed):
        super().__init__(name)  # 调用父类构造函数
        self.breed = breed
    
    def speak(self):
        """重写父类方法"""
        return f"{self.name} 汪汪叫"
    
    def fetch(self):
        """狗特有的方法"""
        return f"{self.name} 在捡球"

class Cat(Animal):
    """猫类"""
    
    def __init__(self, name, color):
        super().__init__(name)
        self.color = color
    
    def speak(self):
        """重写父类方法"""
        return f"{self.name} 喵喵叫"
    
    def climb(self):
        """猫特有的方法"""
        return f"{self.name} 在爬树"

# 多态示例
animals = [
    Dog("旺财", "金毛"),
    Cat("咪咪", "橘色")
]

for animal in animals:
    print(animal.speak())
    print(animal.move())
```
</PythonEditor>

### 2.4 特殊方法（魔术方法）

Python 的特殊方法是其面向对象编程的强大特性，类似于 JavaScript 中的 Symbol 方法。

<PythonEditor title="特殊方法示例" compare={true}>
```javascript !! js
// JavaScript 特殊方法（使用 Symbol）
class Vector {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
    
    // 加法运算
    add(other) {
        return new Vector(this.x + other.x, this.y + other.y);
    }
    
    // 字符串表示
    toString() {
        return `Vector(${this.x}, ${this.y})`;
    }
    
    // 相等比较
    equals(other) {
        return this.x === other.x && this.y === other.y;
    }
    
    // 数组解构
    [Symbol.iterator]() {
        return [this.x, this.y][Symbol.iterator]();
    }
}

const v1 = new Vector(1, 2);
const v2 = new Vector(3, 4);
const v3 = v1.add(v2);

console.log(v1.toString());  // "Vector(1, 2)"
console.log(v3.toString());  // "Vector(4, 6)"
console.log(v1.equals(v2));  // false

// 解构赋值
const [x, y] = v1;
console.log(x, y);  // 1, 2
```

```python !! py
# Python 特殊方法
class Vector:
    """向量类"""
    
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __add__(self, other):
        """加法运算（+ 操作符）"""
        return Vector(self.x + other.x, self.y + other.y)
    
    def __sub__(self, other):
        """减法运算（- 操作符）"""
        return Vector(self.x - other.x, self.y - other.y)
    
    def __mul__(self, scalar):
        """乘法运算（* 操作符）"""
        return Vector(self.x * scalar, self.y * scalar)
    
    def __eq__(self, other):
        """相等比较（== 操作符）"""
        return self.x == other.x and self.y == other.y
    
    def __str__(self):
        """字符串表示（str() 函数）"""
        return f"Vector({self.x}, {self.y})"
    
    def __repr__(self):
        """详细字符串表示（repr() 函数）"""
        return f"Vector({self.x}, {self.y})"
    
    def __len__(self):
        """长度（len() 函数）"""
        return 2
    
    def __getitem__(self, index):
        """索引访问（[] 操作符）"""
        if index == 0:
            return self.x
        elif index == 1:
            return self.y
        else:
            raise IndexError("向量只有两个分量")
    
    def __iter__(self):
        """迭代器（for 循环）"""
        return iter([self.x, self.y])

# 使用特殊方法
v1 = Vector(1, 2)
v2 = Vector(3, 4)

print(v1)                    # Vector(1, 2)
print(v1 + v2)              # Vector(4, 6)
print(v2 - v1)              # Vector(2, 2)
print(v1 * 3)               # Vector(3, 6)
print(v1 == v2)             # False
print(len(v1))              # 2
print(v1[0], v1[1])         # 1, 2

# 迭代
for component in v1:
    print(component)         # 1, 2
```
</PythonEditor>

## 3. 函数式编程特性

### 3.1 高阶函数

Python 支持高阶函数，类似于 JavaScript 中的函数式编程概念。

<PythonEditor title="高阶函数示例" compare={true}>
```javascript !! js
// JavaScript 高阶函数
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// map - 转换数组
const doubled = numbers.map(x => x * 2);
console.log(doubled); // [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

// filter - 过滤数组
const evens = numbers.filter(x => x % 2 === 0);
console.log(evens); // [2, 4, 6, 8, 10]

// reduce - 归约数组
const sum = numbers.reduce((acc, x) => acc + x, 0);
console.log(sum); // 55

// 组合使用
const result = numbers
    .filter(x => x % 2 === 0)
    .map(x => x * 2)
    .reduce((acc, x) => acc + x, 0);
console.log(result); // 60

// 函数作为参数
function applyOperation(numbers, operation) {
    return numbers.map(operation);
}

const squared = applyOperation(numbers, x => x ** 2);
console.log(squared); // [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
```

```python !! py
# Python 高阶函数
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# map - 转换序列
doubled = list(map(lambda x: x * 2, numbers))
print(doubled)  # [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

# filter - 过滤序列
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens)  # [2, 4, 6, 8, 10]

# reduce - 归约序列
from functools import reduce
sum_result = reduce(lambda acc, x: acc + x, numbers, 0)
print(sum_result)  # 55

# 组合使用
result = reduce(
    lambda acc, x: acc + x,
    map(lambda x: x * 2, filter(lambda x: x % 2 == 0, numbers)),
    0
)
print(result)  # 60

# 函数作为参数
def apply_operation(numbers, operation):
    """应用操作到数字列表"""
    return list(map(operation, numbers))

squared = apply_operation(numbers, lambda x: x ** 2)
print(squared)  # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
```
</PythonEditor>

### 3.2 Lambda 函数

Python 的 lambda 函数类似于 JavaScript 的箭头函数，但功能更有限。

<PythonEditor title="Lambda 函数对比" compare={true}>
```javascript !! js
// JavaScript 箭头函数
const add = (a, b) => a + b;
const square = x => x * x;
const isEven = x => x % 2 === 0;

// 多行箭头函数
const processNumber = x => {
    const squared = x * x;
    return squared > 10 ? squared : 0;
};

// 立即执行函数
const result = ((x, y) => x + y)(5, 3);
console.log(result); // 8

// 在数组方法中使用
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(x => x * 2);
const evens = numbers.filter(x => x % 2 === 0);
const sum = numbers.reduce((acc, x) => acc + x, 0);

console.log(doubled); // [2, 4, 6, 8, 10]
console.log(evens);   // [2, 4]
console.log(sum);     // 15
```

```python !! py
# Python lambda 函数
add = lambda a, b: a + b
square = lambda x: x * x
is_even = lambda x: x % 2 == 0

# lambda 函数只能包含单个表达式
# 不能包含多行代码或复杂逻辑

# 立即执行函数
result = (lambda x, y: x + y)(5, 3)
print(result)  # 8

# 在函数式编程中使用
numbers = [1, 2, 3, 4, 5]
doubled = list(map(lambda x: x * 2, numbers))
evens = list(filter(lambda x: x % 2 == 0, numbers))
sum_result = reduce(lambda acc, x: acc + x, numbers, 0)

print(doubled)    # [2, 4, 6, 8, 10]
print(evens)      # [2, 4]
print(sum_result) # 15

# lambda 函数的限制
# 不能包含赋值语句
# 不能包含条件语句（但可以使用三元运算符）
process_number = lambda x: x * x if x > 2 else 0
```
</PythonEditor>

### 3.3 列表推导式

列表推导式是 Python 的特色功能，类似于 JavaScript 的 map 和 filter 的组合。

<PythonEditor title="列表推导式对比" compare={true}>
```javascript !! js
// JavaScript 数组方法
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// 基本映射
const doubled = numbers.map(x => x * 2);

// 条件过滤
const evens = numbers.filter(x => x % 2 === 0);

// 组合操作
const result = numbers
    .filter(x => x % 2 === 0)
    .map(x => x * 2);

// 嵌套数组处理
const matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
const flattened = matrix.flat();
const doubledMatrix = matrix.map(row => row.map(x => x * 2));

console.log(doubled);      // [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
console.log(evens);        // [2, 4, 6, 8, 10]
console.log(result);       // [4, 8, 12, 16, 20]
console.log(flattened);    // [1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log(doubledMatrix); // [[2, 4, 6], [8, 10, 12], [14, 16, 18]]
```

```python !! py
# Python 列表推导式
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# 基本映射
doubled = [x * 2 for x in numbers]

# 条件过滤
evens = [x for x in numbers if x % 2 == 0]

# 组合操作（过滤 + 映射）
result = [x * 2 for x in numbers if x % 2 == 0]

# 嵌套列表处理
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [x for row in matrix for x in row]
doubled_matrix = [[x * 2 for x in row] for row in matrix]

print(doubled)        # [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
print(evens)          # [2, 4, 6, 8, 10]
print(result)         # [4, 8, 12, 16, 20]
print(flattened)      # [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(doubled_matrix) # [[2, 4, 6], [8, 10, 12], [14, 16, 18]]

# 字典推导式
squares = {x: x ** 2 for x in range(5)}
print(squares)  # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

# 集合推导式
unique_squares = {x ** 2 for x in [1, 2, 2, 3, 3, 4]}
print(unique_squares)  # {1, 4, 9, 16}
```
</PythonEditor>

## 4. 装饰器

装饰器是 Python 的独特特性，类似于 JavaScript 中的高阶组件或中间件。

### 4.1 基本装饰器

<PythonEditor title="基本装饰器示例" compare={true}>
```javascript !! js
// JavaScript 高阶函数（类似装饰器）
function logFunction(func) {
    return function(...args) {
        console.log(`调用函数: ${func.name}`);
        console.log(`参数:`, args);
        const result = func(...args);
        console.log(`结果:`, result);
        return result;
    };
}

function add(a, b) {
    return a + b;
}

function multiply(a, b) {
    return a * b;
}

// 应用装饰器
const loggedAdd = logFunction(add);
const loggedMultiply = logFunction(multiply);

loggedAdd(5, 3);
loggedMultiply(4, 2);

// 使用装饰器语法（需要 Babel 插件）
// @logFunction
// function add(a, b) {
//     return a + b;
// }
```

```python !! py
# Python 装饰器
def log_function(func):
    """日志装饰器"""
    def wrapper(*args, **kwargs):
        print(f"调用函数: {func.__name__}")
        print(f"参数: {args}, {kwargs}")
        result = func(*args, **kwargs)
        print(f"结果: {result}")
        return result
    return wrapper

# 使用装饰器语法
@log_function
def add(a, b):
    """加法函数"""
    return a + b

@log_function
def multiply(a, b):
    """乘法函数"""
    return a * b

# 调用函数
add(5, 3)
multiply(4, 2)

# 等价于：
# add = log_function(add)
# multiply = log_function(multiply)
```
</PythonEditor>

### 4.2 带参数的装饰器

<PythonEditor title="带参数的装饰器" compare={true}>
```javascript !! js
// JavaScript 带参数的高阶函数
function retry(maxAttempts = 3, delay = 1000) {
    return function(func) {
        return function(...args) {
            let lastError;
            
            for (let attempt = 1; attempt <= maxAttempts; attempt++) {
                try {
                    console.log(`尝试第 ${attempt} 次`);
                    return func(...args);
                } catch (error) {
                    lastError = error;
                    console.log(`第 ${attempt} 次失败:`, error.message);
                    
                    if (attempt < maxAttempts) {
                        console.log(`等待 ${delay}ms 后重试...`);
                        // 在实际环境中使用 setTimeout
                    }
                }
            }
            
            throw lastError;
        };
    };
}

function unreliableFunction() {
    if (Math.random() < 0.7) {
        throw new Error("随机失败");
    }
    return "成功！";
}

// 应用装饰器
const retryFunction = retry(3, 1000)(unreliableFunction);
// retryFunction();
```

```python !! py
# Python 带参数的装饰器
import time
import random

def retry(max_attempts=3, delay=1):
    """重试装饰器"""
    def decorator(func):
        def wrapper(*args, **kwargs):
            last_error = None
            
            for attempt in range(1, max_attempts + 1):
                try:
                    print(f"尝试第 {attempt} 次")
                    return func(*args, **kwargs)
                except Exception as error:
                    last_error = error
                    print(f"第 {attempt} 次失败: {error}")
                    
                    if attempt < max_attempts:
                        print(f"等待 {delay} 秒后重试...")
                        time.sleep(delay)
            
            raise last_error
        return wrapper
    return decorator

@retry(max_attempts=3, delay=1)
def unreliable_function():
    """不可靠的函数"""
    if random.random() < 0.7:
        raise ValueError("随机失败")
    return "成功！"

# 调用函数
try:
    result = unreliable_function()
    print(f"最终结果: {result}")
except Exception as e:
    print(f"所有尝试都失败了: {e}")
```
</PythonEditor>

### 4.3 类装饰器

<PythonEditor title="类装饰器示例" compare={true}>
```javascript !! js
// JavaScript 类装饰器（概念性）
function singleton(Class) {
    let instance = null;
    
    return class extends Class {
        constructor(...args) {
            if (instance) {
                return instance;
            }
            super(...args);
            instance = this;
        }
    };
}

// 使用装饰器
// @singleton
// class Database {
//     constructor() {
//         this.connection = "数据库连接";
//     }
// }

// 手动应用
class Database {
    constructor() {
        this.connection = "数据库连接";
    }
}

const SingletonDatabase = singleton(Database);
const db1 = new SingletonDatabase();
const db2 = new SingletonDatabase();
console.log(db1 === db2); // true
```

```python !! py
# Python 类装饰器
def singleton(cls):
    """单例装饰器"""
    instances = {}
    
    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    
    return get_instance

@singleton
class Database:
    """数据库类"""
    
    def __init__(self):
        self.connection = "数据库连接"
        print("创建数据库连接")
    
    def query(self, sql):
        return f"执行查询: {sql}"

# 测试单例
db1 = Database()
db2 = Database()
print(db1 is db2)  # True

print(db1.query("SELECT * FROM users"))
print(db2.query("SELECT * FROM products"))
```
</PythonEditor>

## 5. 实际项目示例

### 5.1 数据验证器

让我们创建一个数据验证器，展示面向对象和函数式编程的结合使用。

<PythonEditor title="数据验证器示例" compare={true}>
```javascript !! js
// JavaScript 数据验证器
class Validator {
    constructor() {
        this.rules = [];
    }
    
    addRule(rule) {
        this.rules.push(rule);
        return this;
    }
    
    validate(data) {
        const errors = [];
        
        for (const rule of this.rules) {
            try {
                rule(data);
            } catch (error) {
                errors.push(error.message);
            }
        }
        
        return {
            isValid: errors.length === 0,
            errors
        };
    }
}

// 验证规则
const isString = (data) => {
    if (typeof data !== 'string') {
        throw new Error('必须是字符串');
    }
};

const minLength = (min) => (data) => {
    if (data.length < min) {
        throw new Error(`长度不能少于 ${min} 个字符`);
    }
};

const maxLength = (max) => (data) => {
    if (data.length > max) {
        throw new Error(`长度不能超过 ${max} 个字符`);
    }
};

const pattern = (regex) => (data) => {
    if (!regex.test(data)) {
        throw new Error('格式不正确');
    }
};

// 使用验证器
const userValidator = new Validator()
    .addRule(isString)
    .addRule(minLength(3))
    .addRule(maxLength(20))
    .addRule(pattern(/^[a-zA-Z0-9_]+$/));

const result = userValidator.validate("john_doe");
console.log(JSON.stringify(result, null, 2));
```

```python !! py
# Python 数据验证器
from typing import Callable, List, Dict, Any
import re

class Validator:
    """数据验证器类"""
    
    def __init__(self):
        self.rules: List[Callable] = []
    
    def add_rule(self, rule: Callable) -> 'Validator':
        """添加验证规则"""
        self.rules.append(rule)
        return self
    
    def validate(self, data: Any) -> Dict[str, Any]:
        """验证数据"""
        errors = []
        
        for rule in self.rules:
            try:
                rule(data)
            except ValueError as error:
                errors.append(str(error))
        
        return {
            'is_valid': len(errors) == 0,
            'errors': errors
        }

# 验证规则（函数式风格）
def is_string(data: Any) -> None:
    """检查是否为字符串"""
    if not isinstance(data, str):
        raise ValueError('必须是字符串')

def min_length(min_len: int) -> Callable:
    """最小长度验证器"""
    def validator(data: str) -> None:
        if len(data) < min_len:
            raise ValueError(f'长度不能少于 {min_len} 个字符')
    return validator

def max_length(max_len: int) -> Callable:
    """最大长度验证器"""
    def validator(data: str) -> None:
        if len(data) > max_len:
            raise ValueError(f'长度不能超过 {max_len} 个字符')
    return validator

def pattern(regex: str) -> Callable:
    """正则表达式验证器"""
    def validator(data: str) -> None:
        if not re.match(regex, data):
            raise ValueError('格式不正确')
    return validator

# 使用验证器
user_validator = (Validator()
    .add_rule(is_string)
    .add_rule(min_length(3))
    .add_rule(max_length(20))
    .add_rule(pattern(r'^[a-zA-Z0-9_]+$')))

result = user_validator.validate("john_doe")
print(result)

# 测试无效数据
invalid_result = user_validator.validate("ab")
print(invalid_result)
```
</PythonEditor>

### 5.2 缓存装饰器

<PythonEditor title="缓存装饰器示例" compare={true}>
```javascript !! js
// JavaScript 缓存装饰器
function memoize(func) {
    const cache = new Map();
    
    return function(...args) {
        const key = JSON.stringify(args);
        
        if (cache.has(key)) {
            console.log('从缓存获取结果');
            return cache.get(key);
        }
        
        console.log('计算新结果');
        const result = func(...args);
        cache.set(key, result);
        return result;
    };
}

// 使用缓存装饰器
const expensiveFunction = memoize(function(n) {
    console.log(`计算 ${n} 的阶乘...`);
    let result = 1;
    for (let i = 2; i <= n; i++) {
        result *= i;
    }
    return result;
});

console.log(expensiveFunction(5));  // 计算新结果
console.log(expensiveFunction(5));  // 从缓存获取结果
console.log(expensiveFunction(6));  // 计算新结果
```

```python !! py
# Python 缓存装饰器
from functools import wraps
import json
from typing import Any, Dict

def memoize(func):
    """缓存装饰器"""
    cache: Dict[str, Any] = {}
    
    @wraps(func)
    def wrapper(*args, **kwargs):
        # 创建缓存键
        key = json.dumps((args, sorted(kwargs.items())))
        
        if key in cache:
            print('从缓存获取结果')
            return cache[key]
        
        print('计算新结果')
        result = func(*args, **kwargs)
        cache[key] = result
        return result
    
    return wrapper

@memoize
def expensive_function(n: int) -> int:
    """计算阶乘的昂贵函数"""
    print(f'计算 {n} 的阶乘...')
    result = 1
    for i in range(2, n + 1):
        result *= i
    return result

# 测试缓存
print(expensive_function(5))  # 计算新结果
print(expensive_function(5))  # 从缓存获取结果
print(expensive_function(6))  # 计算新结果

# 使用内置的 lru_cache
from functools import lru_cache

@lru_cache(maxsize=128)
def fibonacci(n: int) -> int:
    """斐波那契数列（带缓存）"""
    if n < 2:
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)

print(fibonacci(10))  # 快速计算，使用缓存
```
</PythonEditor>

## 6. 练习题

### 练习 1：创建学生管理系统

<PythonEditor title="练习题 1：学生管理系统" compare={true}>
```javascript !! js
// 创建学生管理系统
class Student {
    constructor(id, name, age, grades = []) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.grades = grades;
    }
    
    addGrade(grade) {
        this.grades.push(grade);
    }
    
    getAverage() {
        if (this.grades.length === 0) return 0;
        return this.grades.reduce((sum, grade) => sum + grade, 0) / this.grades.length;
    }
    
    toString() {
        return `Student(${this.id}, ${this.name}, ${this.age})`;
    }
}

class StudentManager {
    constructor() {
        this.students = new Map();
    }
    
    addStudent(student) {
        this.students.set(student.id, student);
    }
    
    getStudent(id) {
        return this.students.get(id);
    }
    
    getAllStudents() {
        return Array.from(this.students.values());
    }
    
    getTopStudents(limit = 3) {
        return this.getAllStudents()
            .sort((a, b) => b.getAverage() - a.getAverage())
            .slice(0, limit);
    }
    
    getStudentsByAgeRange(minAge, maxAge) {
        return this.getAllStudents()
            .filter(student => student.age >= minAge && student.age <= maxAge);
    }
}

// 使用示例
const manager = new StudentManager();

const student1 = new Student(1, "张三", 20);
student1.addGrade(85);
student1.addGrade(90);

const student2 = new Student(2, "李四", 19);
student2.addGrade(92);
student2.addGrade(88);

manager.addStudent(student1);
manager.addStudent(student2);

console.log("所有学生:", manager.getAllStudents());
console.log("优秀学生:", manager.getTopStudents(2));
```

```python !! py
# 创建学生管理系统
from typing import List, Dict, Optional
from dataclasses import dataclass, field

@dataclass
class Student:
    """学生类 (使用 dataclass 自动生成 __init__, __repr__ 等)"""
    id: int
    name: str
    age: int
    grades: List[float] = field(default_factory=list)
    
    def add_grade(self, grade: float) -> None:
        """添加成绩"""
        self.grades.append(grade)
    
    def get_average(self) -> float:
        """计算平均分"""
        if not self.grades:
            return 0.0
        return sum(self.grades) / len(self.grades)
    
    def __str__(self) -> str:
        return f"Student({self.id}, {self.name}, {self.age})"

class StudentManager:
    """学生管理器"""
    
    def __init__(self):
        self.students: Dict[int, Student] = {}
    
    def add_student(self, student: Student) -> None:
        """添加学生"""
        self.students[student.id] = student
    
    def get_student(self, student_id: int) -> Optional[Student]:
        """获取学生"""
        return self.students.get(student_id)
    
    def get_all_students(self) -> List[Student]:
        """获取所有学生"""
        return list(self.students.values())
    
    def get_top_students(self, limit: int = 3) -> List[Student]:
        """获取优秀学生"""
        return sorted(
            self.get_all_students(),
            key=lambda s: s.get_average(),
            reverse=True
        )[:limit]
    
    def get_students_by_age_range(self, min_age: int, max_age: int) -> List[Student]:
        """按年龄范围获取学生"""
        return [
            student for student in self.get_all_students()
            if min_age <= student.age <= max_age
        ]

# 使用示例
manager = StudentManager()

student1 = Student(1, "张三", 20)
student1.add_grade(85)
student1.add_grade(90)

student2 = Student(2, "李四", 19)
student2.add_grade(92)
student2.add_grade(88)

manager.add_student(student1)
manager.add_student(student2)

print("所有学生:", manager.get_all_students())
print("优秀学生:", manager.get_top_students(2))
```
</PythonEditor>

### 练习 2：函数式编程练习

<PythonEditor title="练习题 2：函数式编程" compare={true}>
```javascript !! js
// 函数式编程练习
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// 1. 找出所有偶数的平方
const evenSquares = numbers
    .filter(x => x % 2 === 0)
    .map(x => x * x);

// 2. 计算所有奇数的和
const oddSum = numbers
    .filter(x => x % 2 === 1)
    .reduce((sum, x) => sum + x, 0);

// 3. 找出所有大于5的数的立方
const largeCubes = numbers
    .filter(x => x > 5)
    .map(x => x ** 3);

console.log("偶数的平方:", evenSquares);
console.log("奇数的和:", oddSum);
console.log("大于5的数的立方:", largeCubes);
```

```python !! py
# 函数式编程练习
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# 1. 找出所有偶数的平方
even_squares = [x ** 2 for x in numbers if x % 2 == 0]

# 2. 计算所有奇数的和
odd_sum = sum(x for x in numbers if x % 2 == 1)

# 3. 找出所有大于5的数的立方
large_cubes = [x ** 3 for x in numbers if x > 5]

print("偶数的平方:", even_squares)
print("奇数的和:", odd_sum)
print("大于5的数的立方:", large_cubes)

# 使用函数式方法
from functools import reduce

even_squares_func = list(map(lambda x: x ** 2, filter(lambda x: x % 2 == 0, numbers)))
odd_sum_func = reduce(lambda acc, x: acc + x, filter(lambda x: x % 2 == 1, numbers), 0)
large_cubes_func = list(map(lambda x: x ** 3, filter(lambda x: x > 5, numbers)))

print("函数式方法 - 偶数的平方:", even_squares_func)
print("函数式方法 - 奇数的和:", odd_sum_func)
print("函数式方法 - 大于5的数的立方:", large_cubes_func)
```
</PythonEditor>

## 7. 总结

### 关键概念回顾

1. **面向对象编程**
   - 类定义和实例化
   - 继承和多态
   - 特殊方法（魔术方法）
   - 类变量和实例变量

2. **函数式编程**
   - 高阶函数（map, filter, reduce）
   - Lambda 函数
   - 列表推导式
   - 函数作为参数和返回值

3. **装饰器**
   - 基本装饰器
   - 带参数的装饰器
   - 类装饰器
   - 实际应用场景

### JavaScript vs Python 对比总结

| 概念 | JavaScript | Python | 说明 |
|------|------------|--------|------|
| **类定义** | `class ClassName` | `class ClassName:` | Python 使用冒号 |
| **构造函数** | `constructor()` | `__init__(self)` | Python 需要 self 参数 |
| **继承** | `extends` | `(ParentClass)` | Python 使用括号语法 |
| **特殊方法** | Symbol 方法 | `__method__` | Python 更丰富的特殊方法 |
| **高阶函数** | 内置方法 | `map`, `filter`, `reduce` | 概念相同，语法不同 |
| **匿名函数** | 箭头函数 | `lambda` | Python lambda 功能有限 |
| **装饰器** | 高阶函数 | `@decorator` | Python 有语法糖支持 |

### 最佳实践

1. **面向对象编程**
   - 使用 `@dataclass` 简化数据类
   - 合理使用继承和组合
   - 实现适当的特殊方法
   - 遵循单一职责原则

2. **函数式编程**
   - 优先使用列表推导式
   - 合理使用 lambda 函数
   - 避免过度嵌套
   - 保持函数纯净性

3. **装饰器**
   - 使用 `@wraps` 保持函数元数据
   - 合理设计装饰器参数
   - 注意装饰器的执行顺序
   - 避免过度使用装饰器

### 下一步学习

在下一个模块中，我们将学习：
- Python 异步编程（async/await）
- 事件循环机制
- 异步 Web 开发
- 并发编程基础

这些概念将帮助你构建高性能的 Python 应用程序，特别是在 Web 开发和数据处理方面。 